java 扣 脸部特征图 java自动抠图

您所在的位置:网站首页 imageicon java java 扣 脸部特征图 java自动抠图

java 扣 脸部特征图 java自动抠图

2023-06-01 11:29| 来源: 网络整理| 查看: 265

java项目抠图功能

  项目中需要一个上传文字签名并且抠掉背景图的功能,当初第一次听到这个需求时,差点惊掉下巴,我压根都不会觉得java里能实现这功能。但是既然客户需要,那就照办吧。   经过这次功能的实现,我也更加坚定了一个想法,再奇葩的需求,也要先找找方法,不要果断拒绝,要相信Java天下第一,天下第一能有解决不了的事吗?(其实我现在内心已经对学python蠢蠢欲动了,嘿嘿~~~)

1.效果图

  经过我一番的搜索加改造,与前端小伙伴做了下边的效果。(整的跟PS一样,顿时有了高大上的感觉)

java 扣 脸部特征图 java自动抠图_抠图

  功能比较简单,上传图片给后端,后端返回抠完图的路径。

  原图如下:

java 扣 脸部特征图 java自动抠图_Image_02

  上传这个图之后,先框选范围、旋转好方向,注意,框选、旋转图片都是前端的操作,这些前端都有方法,如下图:

java 扣 脸部特征图 java自动抠图_抠图_03

  当设置好之后,则点击抠图,即可看到下图的效果,已经变成了透明的。在这一步操作上,抠图就调用了本次java提供的抠图接口。

java 扣 脸部特征图 java自动抠图_抠图_04

2.扣图接口

  以下是抠图接口,在该接口里前端将裁剪后的图片传送到后端,在该接口里,后端将会把前端传过来的图片传给PictureUtils.transApla(restore,169)方法,在该方法里,将会进行抠图并再保存,保存后将该处理好的图片路径返回给前端,前端直接展示即可。详细步骤如下:

前端上传图片到面板上,此时并没有调用后端接口,仅由前端加载。因为用户上传的图片大小方向都不固定,因此也要考虑一些旋转、裁剪功能,因此这里我们也加入了这些常用功能,经过旋转、裁剪,定好了范围。注意到这里都是前端自己完成。当处理好之后,再调用裁剪接口,也就是下边的代码所写,重点只是PictureUtils.transApla(restore,169)方法。

  如下是裁剪接口:

/** * 签名图扣掉背景色 * @param request * @return */ @RequestMapping(value = "/signHandle",method = RequestMethod.POST) public Object getPsPictureSign(HttpServletRequest request){ MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; String fileName = null; String msg = null; String result = ""; try { //获取文件 Map fileMap = multipartRequest.getFileMap(); if(fileMap == null || fileMap.isEmpty()){ return addResultMapMsg(false,"未上传签名图片"); } MultipartFile multipartFile = null;//获取文件名 for (Map.Entry set : fileMap.entrySet()) { multipartFile = set.getValue();// 文件名 String uploadfileName = multipartFile.getOriginalFilename(); String suffix = uploadfileName.substring(uploadfileName.lastIndexOf(".")+1).toLowerCase(); if(!uploadSuffix.contains(suffix)){ return addResultMapMsg(false,"只能上传 png、jpg 图片格式"); } } //先将文件保存到服务器中,然后操作文件 String fileOriginalName = multipartFile.getOriginalFilename(); String resultStr = File.separator + "pictureTmp" + File.separator + File.separator + fileOriginalName.substring(0,fileOriginalName.lastIndexOf(".")+1) +".png"; fileName = realPath + resultStr; File restore = new File(fileName); if(!restore.getParentFile().exists()){ restore.getParentFile().mkdirs(); } //System.out.println(3+"=="+fileName); multipartFile.transferTo(restore); // 抠图工具类 PictureUtils.transApla(restore,169); // 169为灰色的rcb色值 result = resultStr; } catch (Exception e) { e.printStackTrace(); msg = "处理失败"; } if(!StringUtils.isEmpty(msg)){ //说明上传有错 return addResultMapMsg(false,msg); }else { return addResultMapMsg(true,result.replace("\\","/")); } }

  以下是封装好的工具类,可以直接用,另外,因为使用的方法java直接就有,不需要引用额外的jar包。   如下是工具类方法:

package znxd.lxynzl.controller.photoshop; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.regex.Pattern; /** * Created by lingsf on 2020/6/16. */ public class PictureUtils { public static int color_range = 210; public static Pattern pattern = Pattern.compile("[0-9]*"); public static boolean isNo(String str) { return pattern.matcher(str).matches(); } /** * * @param file 保存后要处理的png文件 * @param rcb 要扣掉的rcb色值 */ public static void transApla(File file,int rcb){ InputStream is=null; try { is = new FileInputStream(file); // 如果是MultipartFile类型,那么自身也有转换成流的方法:is = file.getInputStream(); BufferedImage bi = ImageIO.read(is); Image image = (Image) bi; ImageIcon imageIcon = new ImageIcon(image); BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics(); g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver()); int alpha = 0; color_range = 255 - rcb; // 0 for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage .getHeight(); j1++) { for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage .getWidth(); j2++) { int rgb = bufferedImage.getRGB(j2, j1); if (colorInRange(rgb)) { alpha = 0; } else { alpha = 255; } rgb = (alpha > 16; int green = (color & 0x00ff00) >> 8; int blue = (color & 0x0000ff); if (red >= color_range && green >= color_range && blue >= color_range) { return true; } return false; } }3.总结

  整体功能还是比较简单,后端只提供了一个接口,主要的解决办法,使用了swing的色素替换的方法,就是将固定的色值替换为透明色素,因此功能图上提示用户,尽量用白底黑字的签名上传。   当然你们也看到了,上边的我写的签名图,拍出来也并不是白底黑字,照样也能抠图成功。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3